import type { IResponseData } from '@/service'
import axios from 'axios'
import type {
  AxiosRequestConfig,
  AxiosResponse,
  AxiosInstance,
  InternalAxiosRequestConfig
} from 'axios'
import { ElMessage, ElLoading } from 'element-plus'

interface ICustomConfig<T = AxiosResponse> extends AxiosRequestConfig {
  data?: T
  Interceptors?: IInterceptor<T>
}

let timer: null | number = null;
function debounce(fn: any, delay = 500) {
  // timer 是在闭包中的

  return function(...args: any[]) {
    if (timer) {
      clearTimeout(timer)
    }
    timer = setTimeout(() => {
      fn(...args)
      timer = null
    }, delay)
  }
}
const deEl = debounce((res: any) => {
  ElMessage({
    type: res.code == 0 ? 'success' : 'error',
    message: res.msg
  })
}, 500)
interface IInterceptor<T = AxiosResponse> {
  requestInterceptorsSuccess?: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig
  requestInterceptorsError?: (err: any) => any
  responseInterceptorsSuccess?: (res: T) => T
  responseInterceptorsError?: (err: any) => any
}
let loading: any
class LAxios {
  instance: AxiosInstance
  constructor(config: ICustomConfig) {
    this.instance = axios.create({
      baseURL: config.baseURL,
      timeout: config.timeout
    })
    this.instance.interceptors.request.use(
      (config) => {
        console.log("=> loading");
        
        loading =  ElLoading.service({
          lock: true,
          text: '资源请求中...',
          background: 'rgba(0, 0, 0, 0.7)'
        })
        const i18n_token = localStorage.getItem('i18n_template_userinfo')
        if (i18n_token !== null) {
          config.headers.Authorization = JSON.parse(i18n_token).token
        }
        return config
      },
      (err) => {
        setTimeout(() => loading.close(), 500)
        return err
      }
    )
    this.instance.interceptors.response.use(
      (res) => {
        setTimeout(() => loading.close(), 500)
        deEl(res.data)
        return res.data
      },
      err => {
        setTimeout(() => loading.close(), 500)
        return err
      }
    )
  }
  request<T, R>(method: string, config: ICustomConfig<T>) {
    return new Promise<R>((resolve, reject) => {
      this.instance
        .request<any, R>({
          ...config,
          method
        })
        .then((res) => {
          resolve(res as unknown as R)
        })
        .catch((err) => reject(err))
    })
  }

  get<T = AxiosResponse, R = IResponseData>(config: ICustomConfig<T>) {
    return this.request<T, R>('GET', config)
  }
  patch<T = AxiosResponse, R = IResponseData>(config: ICustomConfig<T>) {
    return this.request<T, R>('Patch', config)
  }
  post<T = AxiosResponse, R = IResponseData>(config: ICustomConfig<T>) {
    return this.request<T, R>('post', config)
  }
  put<T = AxiosResponse, R = IResponseData>(config: ICustomConfig<T>) {
    return this.request<T, R>('PUT', config)
  }
  delete<T = AxiosResponse, R = IResponseData>(config: ICustomConfig<T>) {
    return this.request<T, R>('DELETE', config)
  }
}

export default LAxios;



